﻿using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Sunny.Entity;

namespace Sunny.Service
{
    public class PermissionService
    {
        private readonly SunnyContext _sunnyContext;
        private readonly UserService _userService;

        public PermissionService(SunnyContext sunnyContext,UserService userService)
        {
            _sunnyContext = sunnyContext;
            _userService = userService;
        }

        public async Task<HashSet<string>> GetRoles(SysUser user)
        {
            HashSet<string> roles = new HashSet<string>();
            if (user.IsAdmin())
            {
                roles.Add("admin");
            }
            else
            {
                var roleIds = await _sunnyContext.SysUserRoles.Where(t => t.UserId == user.UserId).Select(t => t.RoleId)
                    .ToListAsync();
                var dbRoles = await _sunnyContext.SysRoles.Where(t => roleIds.Contains(t.RoleId)).ToListAsync();
                foreach (var sysRole in dbRoles)
                {
                    roles.Add(sysRole.RoleKey);
                }
            }

            return roles;
        }

        public async Task<HashSet<string>> GetMenuPermission(SysUser user)
        {
            HashSet<string> perms = new HashSet<string>();
            if (user.IsAdmin())
            {
                perms.Add("*:*:*");
            }
            else
            {
                var roleIds = await _sunnyContext.SysUserRoles.Where(t=>t.UserId == user.UserId).Select(t=>t.RoleId).ToListAsync();
                var menuIds = await _sunnyContext.SysRoleMenus.Where(t=>roleIds.Contains(t.RoleId)).Select(t=>t.MenuId).ToListAsync();
                var dbPerms = await _sunnyContext.SysMenus.Where(t=>menuIds.Contains(t.MenuId)).Select(t=>t.Perms).ToListAsync();
                foreach (var perm in dbPerms)
                {
                    if(!string.IsNullOrEmpty(perm))
                    {
                        perms.Add(perm);
                    }
                }
            }
            return perms;
        }
        
        public bool HasPermission(string code)
        {
            if("*:*".Equals(code) || "*:*:*".Equals(code))
            {
                return true;
            }
            var currentUser = _userService.GetCurrentUser();
            SysUser sysUser = new SysUser(){UserId = currentUser.UserId};
            var permissions = this.GetMenuPermission(sysUser).Result;
            if(permissions.Contains("*:*") || permissions.Contains("*:*:*"))
            {
                return true;
            }
            if(permissions is {Count: > 0})
            {
                if(permissions.Contains(code))
                {
                   return  true;
                }
            }
            return  false;
        }
    }
}